//!
/**
 ***********************************************************************************************************
 * <RBEffectDataContainer implementation>
 ***********************************************************************************************************
 * @file RBEffectDataContainer.cpp
 ***********************************************************************************************************/

/************************************************************************************************************
 * Includes
 ************************************************************************************************************/
#pragma warning(disable: 4996 4244 4100 4189 4127 4505 4701)
#define WIN32
#define STB_DEFINE
#define STB_DEFINE_THREADS
#include "stb.h"

#include "RBEffectDataContainer.h"


/************************************************************************************************************/
RBEffectDataContainer::RBEffectDataContainer()
{
    m_mData = stb_sdict_new(false);
    m_mViews = stb_sdict_new(false);
    m_mSamplers = stb_sdict_new(false);
	RBAssert(m_mData->arena==NULL, "wrong state");
	RBAssert(m_mViews->arena==NULL, "wrong state");
	RBAssert(m_mSamplers->arena==NULL, "wrong state");
}

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
RBEffectDataContainer::~RBEffectDataContainer()
{
	RBAssert(m_mData->arena==NULL, "wrong state");
	stb_sdict_delete(m_mData);
	RBAssert(m_mViews->arena==NULL, "wrong state");
    stb_sdict_delete(m_mViews);
	RBAssert(m_mSamplers->arena==NULL, "wrong state");
    stb_sdict_delete(m_mSamplers);
}

RBEffectDataContainer::RBEffectDataContainer(const RBEffectDataContainer& rhs)
{
    m_mData = stb_sdict_new(false);
    m_mViews = stb_sdict_new(false);
    m_mSamplers = stb_sdict_new(false);
    *this = rhs;
}


/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void RBEffectDataContainer::Clear()
{
    stb_sdict_delete(m_mData);
    stb_sdict_delete(m_mViews);
    stb_sdict_delete(m_mSamplers);

	m_mData = stb_sdict_new(false);
    m_mViews = stb_sdict_new(false);
    m_mSamplers = stb_sdict_new(false);

}

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
void RBEffectDataContainer::AddView( const Key& strName, RBShaderResourceView* pView )
{
	stb_sdict_change(m_mViews, (char*)strName.c_str(), pView);
}

void RBEffectDataContainer::InsertData(char* name, void* data)
{
    stb_sdict_change(m_mData, name, data);
}

/***********************************************************************************************************
 * 
 ***********************************************************************************************************/
RBShaderResourceView* RBEffectDataContainer::GetView( const Key& strName ) const
{
	return (RBShaderResourceView*) stb_sdict_get(m_mViews, (char*)strName.c_str());
}

bool RBEffectDataContainer::get_effect_data_blob( const Key& strName, const void** pData, uint32* size ) const
{
    void* pDataInMap = stb_sdict_get(m_mData, (char*)strName.c_str());
    if (pDataInMap == NULL)
    {
        return false;
    }
    char* pRawDataInMap = (char*)pDataInMap;
    *size = *((uint32*)(pRawDataInMap));
    *pData = (pRawDataInMap+4);

    return true;
}

RBTextureSampler* RBEffectDataContainer::RetrieveSampler( const Key& strName ) const
{
	return (RBTextureSampler*) stb_sdict_get(m_mSamplers, (char*)strName.c_str());
}

RBTextureSampler& RBEffectDataContainer::GetSampler( const Key& strName )
{
	RBTextureSampler* pSampler = RetrieveSampler(strName);
	if	(pSampler==NULL)
	{
		pSampler = new RBTextureSampler;
		stb_sdict_change(m_mSamplers, (char*)strName.c_str(), pSampler);
	}
    return *pSampler;
}

RBEffectDataContainer& RBEffectDataContainer::operator=( const RBEffectDataContainer& rhs )
{
    if (&rhs == this)
    {
        return *this;
    }

    char* key;
    void* val;
    int i;
    stb_sdict_for(rhs.m_mData, i, key, val)
    {
        uint8* pRawDataInMap = (uint8*)val;
        uint32 size = *((uint32*)(pRawDataInMap));
        AddEffectData<uint8>(key, pRawDataInMap, size);
    }

    stb_sdict_for(rhs.m_mViews, i, key, val)
    {
        AddView(key, (RBShaderResourceView*)val);
    }

    stb_sdict_for(rhs.m_mSamplers, i, key, val)
    {
        GetSampler(key);
    }

    return *this;
}
